﻿using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using TestWpf;

namespace TestWpf
{
    public class MouseHook
    {
        private Point point;
        private Point Point {
            get { return point; }
            set {
                if (point != value)
                {
                    point = value;

                    if (getLocationEvent != null)
                    {
                        getLocationEvent(point);
                    }

                    //if (MouseMoveEvent != null)
                    //{
                    //    var e = new RoutedEventArgs(null, point);
                    //    MouseMoveEvent(this, e);
                    //}
                }
            }
        }
        private int hHook;
        private const int WM_LBUTTONDOWN = 0x201;
        public const int WH_MOUSE_LL = 14;
        public Win32Api.HookProc hProc;
        public MouseHook()
        {
            this.Point = new Point();
        }
        public int SetHook()
        {
            hProc = new Win32Api.HookProc(MouseHookProc);
            hHook = Win32Api.SetWindowsHookEx(WH_MOUSE_LL, hProc, IntPtr.Zero, 0);
            return hHook;
        }
        public void UnHook()
        {
            Win32Api.UnhookWindowsHookEx(hHook);
        }
        private int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
        {
            Win32Api.MouseHookStruct MyMouseHookStruct = (Win32Api.MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(Win32Api.MouseHookStruct));
            if (nCode < 0)
            {
                return Win32Api.CallNextHookEx(hHook, nCode, wParam, lParam);
            }
            else
            {
                if (MouseClickEvent != null)
                {
                    MouseButtons button = MouseButtons.None;
                    int clickCount = 0;
                    switch ((Int32)wParam)
                    {
                        case WM_LBUTTONDOWN:
                            button = MouseButtons.Left;
                            clickCount = 1;
                            break;
                    }
                    if (button == MouseButtons.Left)
                    {
                        var e = new RoutedEventArgs(null, point);
                        MouseClickEvent(this, e);
                    }
                }
                this.Point = new Point(MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y);
                return Win32Api.CallNextHookEx(hHook, nCode, wParam, lParam);
            }
        }

        public delegate void MouseMoveHandler(object sender, RoutedEventArgs e);
        public event MouseMoveHandler MouseMoveEvent;

        public delegate void MouseClickHandler(object sender, RoutedEventArgs e);
        public event MouseClickHandler MouseClickEvent;

        public delegate void GetLocationEvent(Point s);
        public event GetLocationEvent getLocationEvent;
    }
}
